home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / drivers / exprraid.c < prev    next >
C/C++ Source or Header  |  2000-04-04  |  18KB  |  557 lines

  1. /***************************************************************************
  2.  
  3. Express Raider - (c) 1986 Data East USA
  4.  
  5. Ernesto Corvi
  6. ernesto@imagina.com
  7.  
  8. Memory Map:
  9. Main CPU: ( 6502 )
  10. 0000-05ff RAM
  11. 0600-07ff Sprites
  12. 0800-0bff Videoram
  13. 0c00-0fff Colorram
  14. 1800-1800 DSW 0
  15. 1801-1801 Controls
  16. 1802-1802 Coins
  17. 1803-1803 DSW 1
  18. 2100-2100 Sound latch write
  19. 2800-2801 Protection
  20. 3800-3800 VBblank ( bootleg only )
  21. 4000-ffff MRA_ROM
  22.  
  23. Sound Cpu: ( 6809 )
  24. 0000-1fff RAM
  25. 2000-2001 YM2203
  26. 4000-4001 YM3526
  27. 6000-6000 Sound latch read
  28. 8000-ffff ROM
  29.  
  30. NOTES:
  31. The main 6502 cpu is a custom one. The differences with a regular 6502 is as follows:
  32. - Extra opcode ( $4b00 ), wich i think reads an external port. VBlank irq is on bit 1 ( 0x02 ).
  33. - Reset, IRQ and NMI vectors are moved.
  34.  
  35. Also, there was some protection circuitry wich is now emulated.
  36.  
  37. The way i dealt with the custom opcode was to change it to return memory
  38. position $ff (wich i verified is not used by the game). And i hacked in
  39. a read handler wich returns the vblank on bit 1. It's an ugly hack, but
  40. works fine.
  41.  
  42. The bootleg version patched the rom to get rid of the extra opcode ( bootlegs
  43. used a regular 6502 ), the vectors hardcoded in place, and also had the
  44. protection cracked.
  45.  
  46. The background tiles had a very ugly encoding. It was so ugly that our
  47. decode gfx routine will not be able to decode it without some little help.
  48. So thats why exprraid_gfx_expand() is there. Many thanks to Phil
  49. Stroffolino, who figured out the encoding.
  50.  
  51. ***************************************************************************/
  52.  
  53. #include "driver.h"
  54. #include "vidhrdw/generic.h"
  55. #include "cpu/m6809/m6809.h"
  56.  
  57. /* from vidhrdw */
  58. extern unsigned char *exprraid_bgcontrol;
  59. void exprraid_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
  60. void exprraid_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom);
  61.  
  62.  
  63. /*****************************************************************************************/
  64. /* Emulate Protection ( only for original express raider, code is cracked on the bootleg */
  65. /*****************************************************************************************/
  66.  
  67. static READ_HANDLER( exprraid_prot_0_r )
  68. {
  69.     unsigned char *RAM = memory_region(REGION_CPU1);
  70.  
  71.     return RAM[0x02a9];
  72. }
  73.  
  74. static READ_HANDLER( exprraid_prot_1_r )
  75. {
  76.     return 0x02;
  77. }
  78.  
  79. static WRITE_HANDLER( sound_cpu_command_w )
  80. {
  81.     soundlatch_w(0,data);
  82.     cpu_cause_interrupt(1,M6809_INT_NMI);
  83. }
  84.  
  85. static READ_HANDLER( vblank_r ) {
  86.     int val = readinputport( 0 );
  87.  
  88.     if ( ( val & 0x02 ) )
  89.         cpu_spin();
  90.  
  91.     return val;
  92. }
  93.  
  94. static struct MemoryReadAddress readmem[] =
  95. {
  96.     { 0x00ff, 0x00ff, vblank_r }, /* HACK!!!! see init_exprraid below */
  97.     { 0x0000, 0x05ff, MRA_RAM },
  98.     { 0x0600, 0x07ff, MRA_RAM }, /* sprites */
  99.     { 0x0800, 0x0bff, videoram_r },
  100.     { 0x0c00, 0x0fff, colorram_r },
  101.     { 0x1800, 0x1800, input_port_1_r }, /* DSW 0 */
  102.     { 0x1801, 0x1801, input_port_2_r }, /* Controls */
  103.     { 0x1802, 0x1802, input_port_3_r }, /* Coins */
  104.     { 0x1803, 0x1803, input_port_4_r }, /* DSW 1 */
  105.     { 0x2800, 0x2800, exprraid_prot_0_r }, /* protection */
  106.     { 0x2801, 0x2801, exprraid_prot_1_r }, /* protection */
  107.     { 0x3800, 0x3800, vblank_r }, /* vblank on bootleg */
  108.     { 0x4000, 0xffff, MRA_ROM },
  109.     { -1 }  /* end of table */
  110. };
  111.  
  112. static struct MemoryWriteAddress writemem[] =
  113. {
  114.     { 0x0000, 0x05ff, MWA_RAM },
  115.     { 0x0600, 0x07ff, MWA_RAM, &spriteram, &spriteram_size }, /* sprites */
  116.     { 0x0800, 0x0bff, videoram_w, &videoram, &videoram_size },
  117.     { 0x0c00, 0x0fff, colorram_w, &colorram },
  118.     { 0x2001, 0x2001, sound_cpu_command_w },
  119.     { 0x2800, 0x2807, MWA_RAM, &exprraid_bgcontrol },
  120.     { 0x4000, 0xffff, MWA_ROM },
  121.     { -1 }  /* end of table */
  122. };
  123.  
  124. static struct MemoryReadAddress sub_readmem[] =
  125. {
  126.     { 0x0000, 0x1fff, MRA_RAM },
  127.     { 0x2000, 0x2000, YM2203_status_port_0_r },
  128.     { 0x2001, 0x2001, YM2203_read_port_0_r },
  129.     { 0x4000, 0x4000, YM3526_status_port_0_r },
  130.     { 0x6000, 0x6000, soundlatch_r },
  131.     { 0x8000, 0xffff, MRA_ROM },
  132.     { -1 }  /* end of table */
  133. };
  134.  
  135. static struct MemoryWriteAddress sub_writemem[] =
  136. {
  137.     { 0x0000, 0x1fff, MWA_RAM },
  138.     { 0x2000, 0x2000, YM2203_control_port_0_w },
  139.     { 0x2001, 0x2001, YM2203_write_port_0_w },
  140.     { 0x4000, 0x4000, YM3526_control_port_0_w },
  141.     { 0x4001, 0x4001, YM3526_write_port_0_w },
  142.     { 0x8000, 0xffff, MWA_ROM },
  143.     { -1 }  /* end of table */
  144. };
  145.  
  146. INPUT_PORTS_START( exprraid )
  147.     PORT_START /* IN 0 - 0x3800 */
  148.     PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_VBLANK )
  149.  
  150.     PORT_START /* DSW 0 - 0x1800 */
  151.     PORT_DIPNAME( 0x03, 0x03, DEF_STR( Coin_A ) )
  152.     PORT_DIPSETTING(    0x00, DEF_STR( 2C_1C ) )
  153.     PORT_DIPSETTING(    0x03, DEF_STR( 1C_1C ) )
  154.     PORT_DIPSETTING(    0x02, DEF_STR( 1C_2C ) )
  155.     PORT_DIPSETTING(    0x01, DEF_STR( 1C_3C ) )
  156.     PORT_DIPNAME( 0x0c, 0x0c, DEF_STR( Coin_B ) )
  157.     PORT_DIPSETTING(    0x00, DEF_STR( 2C_1C ) )
  158.     PORT_DIPSETTING(    0x0c, DEF_STR( 1C_1C ) )
  159.     PORT_DIPSETTING(    0x08, DEF_STR( 1C_2C ) )
  160.     PORT_DIPSETTING(    0x04, DEF_STR( 1C_3C ) )
  161.     PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
  162.     PORT_DIPSETTING(    0x10, DEF_STR( Off ) )
  163.     PORT_DIPSETTING(    0x00, DEF_STR( On ) )
  164.     PORT_DIPNAME( 0x20, 0x20, DEF_STR( Flip_Screen ) )
  165.     PORT_DIPSETTING(    0x20, DEF_STR( Off ) )
  166.     PORT_DIPSETTING(    0x00, DEF_STR( On ) )
  167.     PORT_DIPNAME( 0x40, 0x00, DEF_STR( Cabinet ) )
  168.     PORT_DIPSETTING(    0x00, DEF_STR( Upright ) )
  169.     PORT_DIPSETTING(    0x40, DEF_STR( Cocktail ) )
  170.     PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
  171.     PORT_DIPSETTING(    0x80, DEF_STR( Off ) )
  172.     PORT_DIPSETTING(    0x00, DEF_STR( On ) )
  173.  
  174.     PORT_START /* IN 1 - 0x1801 */
  175.     PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY )
  176.     PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_8WAY )
  177.     PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_8WAY )
  178.     PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_8WAY )
  179.     PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 )
  180.     PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 )
  181.     PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START1 )
  182.     PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START2 )
  183.  
  184.     PORT_START /* IN 2 - 0x1802 */
  185.     PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 )
  186.     PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN2 )
  187.  
  188.     PORT_START /* IN 3 - 0x1803 */
  189.     PORT_DIPNAME( 0x03, 0x03, DEF_STR( Lives ) )
  190.     PORT_DIPSETTING(    0x01, "1" )
  191.     PORT_DIPSETTING(    0x03, "3" )
  192.     PORT_DIPSETTING(    0x02, "5" )
  193.     PORT_BITX( 0,       0x00, IPT_DIPSWITCH_SETTING | IPF_CHEAT, "Infinite", IP_KEY_NONE, IP_JOY_NONE )
  194.     PORT_DIPNAME( 0x04, 0x04, DEF_STR( Bonus_Life ) )
  195.     PORT_DIPSETTING(    0x04, "Every 50000" )
  196.     PORT_DIPSETTING(    0x00, "50000 80000" )
  197.     PORT_DIPNAME( 0x18, 0x18, DEF_STR( Difficulty ) )
  198.     PORT_DIPSETTING(    0x10, "Easy" )
  199.     PORT_DIPSETTING(    0x18, "Normal" )
  200.     PORT_DIPSETTING(    0x08, "Hard" )
  201.     PORT_DIPSETTING(    0x00, "Hardest" )
  202.     PORT_DIPNAME( 0x20, 0x20, DEF_STR( Demo_Sounds ) )
  203.     PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
  204.     PORT_DIPSETTING(    0x20, DEF_STR( On ) )
  205.     PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )    /* This one has to be set for coin up */
  206.     PORT_DIPSETTING(    0x40, DEF_STR( Off ) )
  207.     PORT_DIPSETTING(    0x00, DEF_STR( On ) )
  208.     PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
  209.     PORT_DIPSETTING(    0x80, DEF_STR( Off ) )
  210.     PORT_DIPSETTING(    0x00, DEF_STR( On ) )
  211. INPUT_PORTS_END
  212.  
  213.  
  214.  
  215. static struct GfxLayout charlayout =
  216. {
  217.     8,8,    /* 8*8 characters */
  218.     1024,    /* 1024 characters */
  219.     2,    /* 2 bits per pixel */
  220.     { 0, 4 },    /* the bitplanes are packed in the same byte */
  221.     { (0x2000*8)+0, (0x2000*8)+1, (0x2000*8)+2, (0x2000*8)+3, 0, 1, 2, 3 },
  222.     { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
  223.     8*8    /* every char takes 8 consecutive bytes */
  224. };
  225.  
  226. static struct GfxLayout spritelayout =
  227. {
  228.     16,16,    /* 16*16 sprites */
  229.     2048,    /* 2048 sprites */
  230.     3,    /* 3 bits per pixel */
  231.     { 2*2048*32*8, 2048*32*8, 0 },    /* the bitplanes are separated */
  232.     { 128+0, 128+1, 128+2, 128+3, 128+4, 128+5, 128+6, 128+7, 0, 1, 2, 3, 4, 5, 6, 7 },
  233.     { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8 },
  234.     32*8    /* every char takes 32 consecutive bytes */
  235. };
  236.  
  237. static struct GfxLayout tile1 =
  238. {
  239.     16,16,    /* 16*16 tiles */
  240.     128,    /* 128 tiles */
  241.     3,    /* 3 bits per pixel */
  242.     { 4, 0x10000*8+0, 0x10000*8+4 },
  243.     { 0, 1, 2, 3, 1024*32*2,1024*32*2+1,1024*32*2+2,1024*32*2+3,
  244.         128+0,128+1,128+2,128+3,128+1024*32*2,128+1024*32*2+1,128+1024*32*2+2,128+1024*32*2+3 }, /* BOGUS */
  245.     { 0*8,1*8,2*8,3*8,4*8,5*8,6*8,7*8,
  246.         64+0*8,64+1*8,64+2*8,64+3*8,64+4*8,64+5*8,64+6*8,64+7*8 },
  247.     32*8
  248. };
  249.  
  250. static struct GfxLayout tile2 =
  251. {
  252.     16,16,    /* 16*16 tiles */
  253.     128,    /* 128 tiles */
  254.     3,    /* 3 bits per pixel */
  255.     { 0, 0x11000*8+0, 0x11000*8+4  },
  256.     { 0, 1, 2, 3, 1024*32*2,1024*32*2+1,1024*32*2+2,1024*32*2+3,
  257.         128+0,128+1,128+2,128+3,128+1024*32*2,128+1024*32*2+1,128+1024*32*2+2,128+1024*32*2+3 }, /* BOGUS */
  258.     { 0*8,1*8,2*8,3*8,4*8,5*8,6*8,7*8,
  259.         64+0*8,64+1*8,64+2*8,64+3*8,64+4*8,64+5*8,64+6*8,64+7*8 },
  260.     32*8
  261. };
  262.  
  263.  
  264. static struct GfxDecodeInfo gfxdecodeinfo[] =
  265. {
  266.     { REGION_GFX1, 0x00000, &charlayout,   128, 2 }, /* characters */
  267.     { REGION_GFX2, 0x00000, &spritelayout,  64, 8 }, /* sprites */
  268.     { REGION_GFX3, 0x00000, &tile1,          0, 4 }, /* background tiles */
  269.     { REGION_GFX3, 0x00000, &tile2,          0, 4 },
  270.     { REGION_GFX3, 0x04000, &tile1,          0, 4 },
  271.     { REGION_GFX3, 0x04000, &tile2,          0, 4 },
  272.     { REGION_GFX3, 0x08000, &tile1,          0, 4 },
  273.     { REGION_GFX3, 0x08000, &tile2,          0, 4 },
  274.     { REGION_GFX3, 0x0c000, &tile1,          0, 4 },
  275.     { REGION_GFX3, 0x0c000, &tile2,          0, 4 },
  276.     { -1 } /* end of array */
  277. };
  278.  
  279.  
  280.  
  281. /* handler called by the 3812 emulator when the internal timers cause an IRQ */
  282. static void irqhandler(int linestate)
  283. {
  284.     cpu_set_irq_line(1,0,linestate);
  285.     //cpu_cause_interrupt(1,0xff);
  286. }
  287.  
  288. static struct YM2203interface ym2203_interface =
  289. {
  290.     1,      /* 1 chip */
  291.     1500000,        /* 1.5 MHz ??? */
  292.     { YM2203_VOL(30,30) },
  293.     { 0 },
  294.     { 0 },
  295.     { 0 },
  296.     { 0 }
  297. };
  298.  
  299. static struct YM3526interface ym3526_interface =
  300. {
  301.     1,                      /* 1 chip (no more supported) */
  302.     3600000,    /* 3.600000 MHz ? (partially supported) */
  303.     { 30 },        /* volume */
  304.     { irqhandler }
  305. };
  306.  
  307. static int exprraid_interrupt(void)
  308. {
  309.     static int coin = 0;
  310.  
  311.     if ( ( ~readinputport( 3 ) ) & 0xc0 ) {
  312.         if ( coin == 0 ) {
  313.             coin = 1;
  314.             return nmi_interrupt();
  315.         }
  316.     } else
  317.         coin = 0;
  318.  
  319.     return ignore_interrupt();
  320. }
  321.  
  322. static struct MachineDriver machine_driver_exprraid =
  323. {
  324.     /* basic machine hardware */
  325.     {
  326.         {
  327.             CPU_M6502,
  328.             4000000,        /* 4 Mhz ??? */
  329.             readmem,writemem,0,0,
  330.             exprraid_interrupt, 1
  331.         },
  332.         {
  333.             CPU_M6809,
  334.             2000000,        /* 2 Mhz ??? */
  335.             sub_readmem,sub_writemem,0,0,
  336.             ignore_interrupt,0    /* NMIs are caused by the main CPU */
  337.                                 /* IRQs are caused by the YM3526 */
  338.         }
  339.     },
  340.     60, DEFAULT_REAL_60HZ_VBLANK_DURATION,  /* frames per second, vblank duration */
  341.     1, /* 1 CPU slice per frame - interleaving is forced when a sound command is written */
  342.     0,
  343.  
  344.     /* video hardware */
  345.     32*8, 32*8, { 1*8, 31*8-1, 1*8, 31*8-1 },
  346.     gfxdecodeinfo,
  347.     256, 256,
  348.     exprraid_vh_convert_color_prom,
  349.  
  350.     VIDEO_TYPE_RASTER | VIDEO_SUPPORTS_DIRTY,
  351.     0,
  352.     generic_vh_start,
  353.     generic_vh_stop,
  354.     exprraid_vh_screenrefresh,
  355.  
  356.     /* sound hardware */
  357.     0,0,0,0,
  358.     {
  359.         {
  360.             SOUND_YM2203,
  361.             &ym2203_interface
  362.         },
  363.         {
  364.             SOUND_YM3526,
  365.             &ym3526_interface
  366.         }
  367.     }
  368. };
  369.  
  370.  
  371.  
  372. /***************************************************************************
  373.  
  374.   Game driver(s)
  375.  
  376. ***************************************************************************/
  377.  
  378. ROM_START( exprraid )
  379.     ROM_REGION( 0x10000, REGION_CPU1 )    /* 64k for code */
  380.     ROM_LOAD( "cz01",    0x4000, 0x4000, 0xdc8f9fba )
  381.     ROM_LOAD( "cz00",    0x8000, 0x8000, 0xa81290bc )
  382.  
  383.     ROM_REGION( 0x10000, REGION_CPU2 )    /* 64k for the sub cpu */
  384.     ROM_LOAD( "cz02",    0x8000, 0x8000, 0x552e6112 )
  385.  
  386.     ROM_REGION( 0x04000, REGION_GFX1 | REGIONFLAG_DISPOSE )
  387.     ROM_LOAD( "cz07",    0x00000, 0x4000, 0x686bac23 )    /* characters */
  388.  
  389.     ROM_REGION( 0x30000, REGION_GFX2 | REGIONFLAG_DISPOSE )
  390.     ROM_LOAD( "cz09",    0x00000, 0x8000, 0x1ed250d1 )    /* sprites */
  391.     ROM_LOAD( "cz08",    0x08000, 0x8000, 0x2293fc61 )
  392.     ROM_LOAD( "cz13",    0x10000, 0x8000, 0x7c3bfd00 )
  393.     ROM_LOAD( "cz12",    0x18000, 0x8000, 0xea2294c8 )
  394.     ROM_LOAD( "cz11",    0x20000, 0x8000, 0xb7418335 )
  395.     ROM_LOAD( "cz10",    0x28000, 0x8000, 0x2f611978 )
  396.  
  397.     ROM_REGION( 0x20000, REGION_GFX3 | REGIONFLAG_DISPOSE )
  398.     ROM_LOAD( "cz04",    0x00000, 0x8000, 0x643a1bd3 )    /* tiles */
  399.     /* Save 0x08000-0x0ffff to expand the previous so we can decode the thing */
  400.     ROM_LOAD( "cz05",    0x10000, 0x8000, 0xc44570bf )    /* tiles */
  401.     ROM_LOAD( "cz06",    0x18000, 0x8000, 0xb9bb448b )    /* tiles */
  402.  
  403.     ROM_REGION( 0x8000, REGION_GFX4 )     /* background tilemaps */
  404.     ROM_LOAD( "cz03",    0x0000, 0x8000, 0x6ce11971 )
  405.  
  406.     ROM_REGION( 0x0400, REGION_PROMS )
  407.     ROM_LOAD( "cz17.prm", 0x0000, 0x0100, 0xda31dfbc ) /* red */
  408.     ROM_LOAD( "cz16.prm", 0x0100, 0x0100, 0x51f25b4c ) /* green */
  409.     ROM_LOAD( "cz15.prm", 0x0200, 0x0100, 0xa6168d7f ) /* blue */
  410.     ROM_LOAD( "cz14.prm", 0x0300, 0x0100, 0x52aad300 ) /* ??? */
  411. ROM_END
  412.  
  413. ROM_START( wexpress )
  414.     ROM_REGION( 0x10000, REGION_CPU1 )    /* 64k for code */
  415.     ROM_LOAD( "2",       0x4000, 0x4000, 0xea5e5a8f )
  416.     ROM_LOAD( "1",       0x8000, 0x8000, 0xa7daae12 )
  417.  
  418.     ROM_REGION( 0x10000, REGION_CPU2 )    /* 64k for the sub cpu */
  419.     ROM_LOAD( "cz02",    0x8000, 0x8000, 0x552e6112 )
  420.  
  421.     ROM_REGION( 0x04000, REGION_GFX1 | REGIONFLAG_DISPOSE )
  422.     ROM_LOAD( "cz07",    0x00000, 0x4000, 0x686bac23 )    /* characters */
  423.  
  424.     ROM_REGION( 0x30000, REGION_GFX2 | REGIONFLAG_DISPOSE )
  425.     ROM_LOAD( "cz09",    0x00000, 0x8000, 0x1ed250d1 )    /* sprites */
  426.     ROM_LOAD( "cz08",    0x08000, 0x8000, 0x2293fc61 )
  427.     ROM_LOAD( "cz13",    0x10000, 0x8000, 0x7c3bfd00 )
  428.     ROM_LOAD( "cz12",    0x18000, 0x8000, 0xea2294c8 )
  429.     ROM_LOAD( "cz11",    0x20000, 0x8000, 0xb7418335 )
  430.     ROM_LOAD( "cz10",    0x28000, 0x8000, 0x2f611978 )
  431.  
  432.     ROM_REGION( 0x20000, REGION_GFX3 | REGIONFLAG_DISPOSE )
  433.     ROM_LOAD( "4",       0x00000, 0x8000, 0xf2e93ff0 )    /* tiles */
  434.     /* Save 0x08000-0x0ffff to expand the previous so we can decode the thing */
  435.     ROM_LOAD( "cz05",    0x10000, 0x8000, 0xc44570bf )    /* tiles */
  436.     ROM_LOAD( "6",       0x18000, 0x8000, 0xc3a56de5 )    /* tiles */
  437.  
  438.     ROM_REGION( 0x8000, REGION_GFX4 )     /* background tilemaps */
  439.     ROM_LOAD( "3",        0x0000, 0x8000, 0x242e3e64 )
  440.  
  441.     ROM_REGION( 0x0400, REGION_PROMS )
  442.     ROM_LOAD( "cz17.prm", 0x0000, 0x0100, 0xda31dfbc ) /* red */
  443.     ROM_LOAD( "cz16.prm", 0x0100, 0x0100, 0x51f25b4c ) /* green */
  444.     ROM_LOAD( "cz15.prm", 0x0200, 0x0100, 0xa6168d7f ) /* blue */
  445.     ROM_LOAD( "cz14.prm", 0x0300, 0x0100, 0x52aad300 ) /* ??? */
  446. ROM_END
  447.  
  448. ROM_START( wexpresb )
  449.     ROM_REGION( 0x10000, REGION_CPU1 )    /* 64k for code */
  450.     ROM_LOAD( "wexpress.3", 0x4000, 0x4000, 0xb4dd0fa4 )
  451.     ROM_LOAD( "wexpress.1", 0x8000, 0x8000, 0xe8466596 )
  452.  
  453.     ROM_REGION( 0x10000, REGION_CPU2 )    /* 64k for the sub cpu */
  454.     ROM_LOAD( "cz02",    0x8000, 0x8000, 0x552e6112 )
  455.  
  456.     ROM_REGION( 0x04000, REGION_GFX1 | REGIONFLAG_DISPOSE )
  457.     ROM_LOAD( "cz07",    0x00000, 0x4000, 0x686bac23 )    /* characters */
  458.  
  459.     ROM_REGION( 0x30000, REGION_GFX2 | REGIONFLAG_DISPOSE )
  460.     ROM_LOAD( "cz09",    0x00000, 0x8000, 0x1ed250d1 )    /* sprites */
  461.     ROM_LOAD( "cz08",    0x08000, 0x8000, 0x2293fc61 )
  462.     ROM_LOAD( "cz13",    0x10000, 0x8000, 0x7c3bfd00 )
  463.     ROM_LOAD( "cz12",    0x18000, 0x8000, 0xea2294c8 )
  464.     ROM_LOAD( "cz11",    0x20000, 0x8000, 0xb7418335 )
  465.     ROM_LOAD( "cz10",    0x28000, 0x8000, 0x2f611978 )
  466.  
  467.     ROM_REGION( 0x20000, REGION_GFX3 | REGIONFLAG_DISPOSE )
  468.     ROM_LOAD( "4",       0x00000, 0x8000, 0xf2e93ff0 )    /* tiles */
  469.     /* Save 0x08000-0x0ffff to expand the previous so we can decode the thing */
  470.     ROM_LOAD( "cz05",    0x10000, 0x8000, 0xc44570bf )    /* tiles */
  471.     ROM_LOAD( "6",       0x18000, 0x8000, 0xc3a56de5 )    /* tiles */
  472.  
  473.     ROM_REGION( 0x8000, REGION_GFX4 )     /* background tilemaps */
  474.     ROM_LOAD( "3",        0x0000, 0x8000, 0x242e3e64 )
  475.  
  476.     ROM_REGION( 0x0400, REGION_PROMS )
  477.     ROM_LOAD( "cz17.prm", 0x0000, 0x0100, 0xda31dfbc ) /* red */
  478.     ROM_LOAD( "cz16.prm", 0x0100, 0x0100, 0x51f25b4c ) /* green */
  479.     ROM_LOAD( "cz15.prm", 0x0200, 0x0100, 0xa6168d7f ) /* blue */
  480.     ROM_LOAD( "cz14.prm", 0x0300, 0x0100, 0x52aad300 ) /* ??? */
  481. ROM_END
  482.  
  483.  
  484.  
  485. static void exprraid_gfx_expand(void)
  486. {
  487.     /* Expand the background rom so we can use regular decode routines */
  488.  
  489.     unsigned char    *gfx = memory_region(REGION_GFX3);
  490.     int                offs = 0x10000-0x1000;
  491.     int                i;
  492.  
  493.  
  494.     for ( i = 0x8000-0x1000; i >= 0; i-= 0x1000 )
  495.     {
  496.         memcpy( &(gfx[offs]), &(gfx[i]), 0x1000 );
  497.  
  498.         offs -= 0x1000;
  499.  
  500.         memcpy( &(gfx[offs]), &(gfx[i]), 0x1000 );
  501.  
  502.         offs -= 0x1000;
  503.     }
  504. }
  505.  
  506.  
  507. static void init_wexpress(void)
  508. {
  509.     unsigned char *rom = memory_region(REGION_CPU1);
  510.     int i;
  511.  
  512.  
  513.     exprraid_gfx_expand();
  514.  
  515.     /* HACK!: Implement custom opcode as regular with a mapped io read */
  516.     for ( i = 0; i < 0x10000; i++ )
  517.     {
  518.         /* make sure is what we want to patch */
  519.         if ( rom[i] == 0x4b && rom[i+1] == 0x00 && rom[i+2] == 0x29 && rom[i+3] == 0x02 )
  520.         {
  521.             /* replace custom opcode with: LDA    $FF */
  522.             rom[i] = 0xa5;
  523.             i++;
  524.             rom[i] = 0xff;
  525.         }
  526.     }
  527. }
  528.  
  529. static void init_exprraid(void)
  530. {
  531.     unsigned char *rom = memory_region(REGION_CPU1);
  532.  
  533.  
  534.     /* decode vectors */
  535.     rom[0xfffa] = rom[0xfff7];
  536.     rom[0xfffb] = rom[0xfff6];
  537.  
  538.     rom[0xfffc] = rom[0xfff1];
  539.     rom[0xfffd] = rom[0xfff0];
  540.  
  541.     rom[0xfffe] = rom[0xfff3];
  542.     rom[0xffff] = rom[0xfff2];
  543.  
  544.     /* HACK!: Implement custom opcode as regular with a mapped io read */
  545.     init_wexpress();
  546. }
  547.  
  548. static void init_wexpresb(void)
  549. {
  550.     exprraid_gfx_expand();
  551. }
  552.  
  553.  
  554. GAMEX( 1986, exprraid, 0,        exprraid, exprraid, exprraid, ROT0, "Data East USA", "Express Raider (US)", GAME_NO_COCKTAIL )
  555. GAMEX( 1986, wexpress, exprraid, exprraid, exprraid, wexpress, ROT0, "Data East Corporation", "Western Express (World?)", GAME_NO_COCKTAIL )
  556. GAMEX( 1986, wexpresb, exprraid, exprraid, exprraid, wexpresb, ROT0, "bootleg", "Western Express (bootleg)", GAME_NO_COCKTAIL )
  557.